﻿namespace Collaboris.Utils
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;

    /// <summary>
    /// Ftp Helper Library
    /// </summary>
    public class FtpHelper
    {

        /// <summary>
        /// Creates a directory in a remote FTP site.
        /// </summary>
        /// <param name="ftpAddress">The FTP address.</param>
        /// <param name="directoryName">Name of the directory.</param>
        /// <param name="username">The username.</param>
        /// <param name="password">The password.</param>
        public static void CreateDirectory(string ftpAddress, string directoryName, string username, string password)
        {
            ValidationHelper.VerifyStringArgument(ftpAddress, "ftpAddress");
            ValidationHelper.VerifyStringArgument(directoryName, "directoryName");
            ValidationHelper.VerifyStringArgument(username, "username");
            ValidationHelper.VerifyStringArgument(password, "password");
            directoryName = directoryName.Trim();
            
            FtpWebRequest ftpw = (FtpWebRequest)(FtpWebRequest.Create(new Uri(ftpAddress + directoryName)));
            ftpw.Method = WebRequestMethods.Ftp.MakeDirectory;
            ftpw.Credentials = new NetworkCredential(username, password); 
            FtpWebResponse fr = (FtpWebResponse)(ftpw.GetResponse()); 
            Stream stream = fr.GetResponseStream(); 
            stream.Close(); 
            fr.Close();
        }


        /// <summary>
        /// Uploads the file.
        /// </summary>
        /// <param name="ftpAddress">The FTP address.</param>
        /// <param name="filePath">The file path.</param>
        /// <param name="username">The username.</param>
        /// <param name="password">The password.</param>
        public static void UploadFile(string ftpAddress, string filePath, string username, string password)
        {
            // validate
            ValidationHelper.VerifyStringArgument(ftpAddress, "ftpAddress");
            ValidationHelper.VerifyStringArgument(filePath, "filePath");

            if (!File.Exists(filePath))
                throw new FileNotFoundException("Cannot FTP file as it can't be found.", filePath);
            
            // Get the request object
            FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(ftpAddress + "/" + Path.GetFileName(filePath));
            request.Method = WebRequestMethods.Ftp.UploadFile; 
            if (!string.IsNullOrEmpty(username))
                request.Credentials = new NetworkCredential(username, password); 

            request.UsePassive = true; 
            request.UseBinary = true; 
            request.KeepAlive = false;
            
            // Open the file
            FileStream stream = File.OpenRead(filePath); 
            byte[] buffer = new byte[stream.Length];
            stream.Read(buffer, 0, buffer.Length); 
            stream.Close();

            // Write the file to the FTP Stream
            Stream reqStream = request.GetRequestStream(); 
            reqStream.Write(buffer, 0, buffer.Length); 
            reqStream.Close();


        }

        /// <summary>
        /// Uploads the file.
        /// </summary>
        /// <param name="ftpAddress">The FTP address.</param>
        /// <param name="fileNames">The file names.</param>
        /// <param name="userName">Name of the user.</param>
        /// <param name="password">The password.</param>
        /// <param name="stopOnException">if set to <c>true</c> [stop on exception].</param>
        /// <returns></returns>
        public static bool UploadFile(string ftpAddress, List<string> fileNames, string userName, string password, bool stopOnException)
        {
            bool success = true;
            foreach (string fileName in fileNames)
            {
                try
                {
                    UploadFile(ftpAddress, fileName, userName, password);
                }
                catch
                {
                    success = false;
                    if (stopOnException)
                        throw;
                }
            }

            return success;
        }
    }
}
